﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mpfr;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Mpfr.Structs;
using NumberInterface;

namespace MpfrTest
{
  /// <summary>
  /// Summary description for BasicUseTest
  /// </summary>
  [TestClass]
  public unsafe class BasicUseTest
  {
    [TestMethod]
    public void SimpleTest()
    {
      uint i;
      var t = new mpfr_t();
      var s = new mpfr_t();
      var u = new mpfr_t();
      var r = new mpfr_t();

      MpfrImport.init2(t, 200);
      MpfrImport.init2(s, 200);
      MpfrImport.init2(u, 200);

      MpfrImport.set_d(t, 1.0, mpfr_rnd_t.GMP_RNDD);
      MpfrImport.set_d(s, 1.0, mpfr_rnd_t.GMP_RNDD);

      MpfrImport.init_set(r, t, mpfr_rnd_t.GMP_RNDD);
      MpfrImport.tan(r, r, mpfr_rnd_t.GMP_RNDN);
      MpfrImport.tanh(r, r, mpfr_rnd_t.GMP_RNDN);
      
      for (i = 1; i < 100; i++)
      {
        MpfrImport.mul_ui(t, t, i, mpfr_rnd_t.GMP_RNDU);
        MpfrImport.set_d(u, 1.0, mpfr_rnd_t.GMP_RNDD);
        MpfrImport.div(u, u, t, mpfr_rnd_t.GMP_RNDD);
        MpfrImport.add(s, s, u, mpfr_rnd_t.GMP_RNDD);
      }

      string text = string.Format("Sum is {0}", MpfrImport.snprintf("%.20000Rg", s));

      MpfrImport.clear(u);
      MpfrImport.clear(s);
      MpfrImport.clear(t);
      u.Dispose();
      s.Dispose();
      t.Dispose();
    }

    [TestMethod]
    public void SetStrTest()
    {
      var t = new mpfr_t();
      MpfrImport.init2(t, 200);
      MpfrImport.set_str(t, "123", 10, mpfr_rnd_t.GMP_RNDD);
      string text = MpfrImport.snprintf("%.2000Rg", t);
      MpfrImport.clear(t);
      t.Dispose();
    }

    [TestMethod]
    public void ASinTest()
    {
        var t = new mpfr_t();

        MpfrImport.init2(t, 200);

        MpfrImport.asin(t, t, mpfr_rnd_t.GMP_RNDD);

        MpfrImport.clear(t);
    }

    [TestMethod]
    public void DoubleTest()
    {
      var t = new mpfr_t();

      MpfrImport.init2(t, 200);

      MpfrImport.set_d(t, 1.2, mpfr_rnd_t.GMP_RNDU);
      MpfrImport.add_d(t, t, .1, mpfr_rnd_t.GMP_RNDU);

      string text = MpfrImport.snprintf("%.2000Rg", t);

      MpfrImport.clear(t);
    }

    [TestMethod]
    public void AddSITest()
    {
      var t = new mpfr_t();

      MpfrImport.init2(t, 200);

      MpfrImport.set_str(t, "1", 10, mpfr_rnd_t.GMP_RNDN);

      MpfrImport.add_si(t, t, int.MaxValue, mpfr_rnd_t.GMP_RNDN);

      string text = MpfrImport.snprintf("%.2000Rg", t);
      uint dp = MpfrImport.get_default_prec();

      string version = MpfrImport.get_version();

      MpfrImport.clear(t);
    }

    [TestMethod]
    public void Add1Test()
    {
      var a = new mpfr_t();
      var b = new mpfr_t();
      var dst = new mpfr_t();

      MpfrImport.init2(a, 200);
      MpfrImport.init2(b, 200);
      MpfrImport.init2(dst, 200);

      MpfrImport.set_d(a, 1, mpfr_rnd_t.GMP_RNDN);
      MpfrImport.set_d(b, 2, mpfr_rnd_t.GMP_RNDN);

      string result = MpfrImport.snprintf("%.2000Rg", dst);
      MpfrImport.add(dst, a, b, mpfr_rnd_t.GMP_RNDN);
      result = MpfrImport.snprintf("%.2000Rg", dst);

      MpfrImport.clear(b);
      MpfrImport.clear(a);
    }

    [TestMethod]
    public void ObjectTest()
    {
      MpfrNumber num = new MpfrNumber();
      num.Assign(10);
      num.Add(1);
      int i = num.ToInt();
      Assert.AreEqual(11, i, "foo");
    }

    [TestMethod]
    public void ObjectTest2()
    {
      Type t = typeof(MpfrNumber);
      INumber n;

      System.Reflection.ConstructorInfo ci = t.GetConstructor(new Type[] { });
      n = (INumber)ci.Invoke(new Type[] { });
    }
  }
}
